<?php
declare (strict_types=1);

namespace app\common\model;


use helper\Arr;
use think\facade\Cache;
use think\model;

/**
 * @mixin \think\model;
 */
class Region extends Model
{
    /**
     * 获取区域
     * @param $param
     * @return array
     */
    public static function getList($param)
    {
        $param['status'] = $param['status'] ?? 0;
        $key   = 'region:' . $param['subdistrict'] . $param['keywords'];
        $redis = Cache::store('redis');
        if ($redis->has($key) && $param['status'] == 0) {
            return $redis->get($key);
        }

        $where = [];
        if ($param['keywords']) {
            if (!is_numeric($param['keywords'])) {
                $param['keywords'] = Region::where('name', 'like', $param['keywords'] . '%')
                    ->order('adcode', 'asc')
                    ->value('adcode');
                if (!$param['keywords']) {
                    return [];
                }
            }
            $where[] = ['adcode', '<>', $param['keywords']];
            $where[] = ['adcode', 'like', "{$param['keywords']}%"];
        }

        $array   = [1 => 'county', 2 => 'province', 4 => 'city', 6 => 'district', 9 => 'street', 12 => 'village', 14 => 'group'];
        $offset  = array_search(strlen((string)$param['keywords']), array_keys($array));
        $level   = array_slice($array, $offset + 1, (int)$param['subdistrict']);
        $where[] = ['level', 'in', $level];

        $list = Region::where($where)->order('adcode', 'ASC')->select();
        $list = Arr::subTree($list->toArray(), (int)$param['keywords'], 'children', 'adcode', 'parent_adcode');
        if ($param['status'] == 0) {
            $redis->set($key, $list, 7200);
        }
        return $list;
    }

    public static function getParents($pid, $array = [])
    {
        $parent  = Region::where("adcode", $pid)->find()->toArray();
        $array[] = $parent;
        if ($parent["parent_adcode"]) {
            return self::getParents($parent['parent_adcode'], $array);
        }
        return $array;
    }

    /**
     * 行政区划信息
     * @param $adcode
     * @param string $address
     * @return array
     */
    public static function setAdInfo($adcode, $address = '')
    {
        $region = Region::getSub($adcode);
        return [
            "adcode"        => $region['adcode'] ?? 0,
            "name"          => $region['name'] ?? '',
            "province"      => $region['province'] ?? '',
            "province_code" => $region['province_code'] ?? 0,
            "city"          => $region['city'] ?? '',
            "city_code"     => $region['city_code'] ?? 0,
            "district"      => $region['district'] ?? '',
            "district_code" => $region['district_code'] ?? 0,
            "street"        => $region['street'] ?? '',
            "street_code"   => $region['street_code'] ?? 0,
            "village"       => $region['village'] ?? '',
            "village_code"  => $region['village_code'] ?? 0,
            "group"         => $region['group'] ?? '',
            "group_code"    => $region['group_code'] ?? 0,
            "address"       => $address,
            "location"      => [
                "lat" => '',
                "lng" => ''
            ]
        ];
    }

    /**
     * 获取代码
     * @param $adcode
     * @param int $level
     * @return array
     */
    public static function getSub($adcode, int $level = 5)
    {
        $code  = substr((string)$adcode, 0, 2);
        $key   = 'region:' . $code;
        $redis = Cache::store('redis');
        if (!$redis->has($key)) {
            $data = Region::where("adcode", 'like', $code . '%')->select()->toArray();
            $redis->set($key, $data, 7200);
        }
        $data = $redis->get($key);
        $arr  = [];
        $i    = 0;
        foreach ($data as $item) {
            if (strpos((string)$adcode, (string)$item['adcode']) !== false) {
                if ($i == $level) {
                    break;
                }
                $arr['adcode'] = $item['adcode'];
                switch ($i) {
                    case 0:
                        $arr['name']          = $item['name'];
                        $arr['province']      = $item['name'];
                        $arr['province_code'] = $arr['adcode'];
                        break;
                    case 1:
                        $arr['name']      .= ',' . $item['name'];
                        $arr['city']      = $item['name'];
                        $arr['city_code'] = $arr['adcode'];
                        break;
                    case 2:
                        $arr['name']          .= ',' . $item['name'];
                        $arr['district']      = $item['name'];
                        $arr['district_code'] = $arr['adcode'];
                        break;
                    case 3:
                        $arr['name']        .= ',' . $item['name'];
                        $arr['street']      = $item['name'];
                        $arr['street_code'] = $arr['adcode'];
                        break;
                    case 4:
                        $arr['name']         .= ',' . $item['name'];
                        $arr['village']      = $item['name'];
                        $arr['village_code'] = $arr['adcode'];
                        break;
                    case 5:
                        $arr['name']         .= ',' . $item['name'];
                        $arr['group']        = $item['name'];
                        $arr['group_code']   = $arr['adcode'];
                        break;
                }
                $i++;
            }
        }
        return $arr;
    }

    /**
     * 获取用户信息
     * @return array
     */
    public static function region_open()
    {
        $key   = 'region_open';
        $redis = Cache::store('redis');
        if (!$redis->has($key)) {
            $data = Region::column('adcode');
            $redis->set($key, $data, 7200);
            return $data;
        }
        return $redis->get($key);
    }

    /**
     * 获取最多四级行政区 乡镇街道adcode不对
     * @param int $level
     * @return bool
     */
    public function map(int $level = 3)
    {
        $url      = 'http://restapi.amap.com/v3/config/district?key=5f6d1733b6b08927f8c44f9fd70e1026&subdistrict=' . $level;
        $response = file_get_contents($url);
        $res      = json_decode($response);
        $data     = $res->districts[0]->districts;
        foreach ($data as $d1) {
            //插入省
            self::create([
                'adcode' => $d1->adcode,
                'name'   => $d1->name,
                'level'  => $d1->level
            ]);
            if (isset($d1->districts) && !empty($d1->districts)) {
                foreach ($d1->districts as $d2) {
                    //插入市
                    self::create([
                        'adcode'        => $d2->adcode,
                        'name'          => $d2->name,
                        'level'         => $d2->level,
                        'parent_adcode' => $d1->adcode
                    ]);
                    if (isset($d2->districts) && !empty($d2->districts)) {
                        foreach ($d2->districts as $d3) {
                            //插入区县
                            self::create([
                                'adcode'        => $d3->adcode,
                                'name'          => $d3->name,
                                'level'         => $d3->level,
                                'parent_adcode' => $d2->adcode
                            ]);
                            if (isset($d3->districts) && !empty($d3->districts)) {
                                foreach ($d3->districts as $d4) {
                                    //插入乡镇
                                    self::create([
                                        'adcode'        => $d4->adcode,
                                        'name'          => $d4->name,
                                        'level'         => $d4->level,
                                        'parent_adcode' => $d3->adcode
                                    ]);
                                }
                            }
                        }
                    }
                }
            }
        }
        return true;
    }
}
